#pragma once


#define RESERVED_SRC        0x0100
#define RESERVED_CODE       0x0200

#define TK_EOS 0
enum{
    TK_LET = RESERVED_SRC,

    TK_TRUE, TK_FALSE,
    TK_BOOL, TK_INT,  TK_LONG,
    TK_FLOAT, TK_DOUBLE, TK_TSTRING,
    TK_IF, TK_ELSE,

    TK_EQ, TK_GE, TK_LE, TK_NE,
    TK_SHL, TK_SHR,
    TK_NUMBER, TK_NAME, TK_STR,
};

enum{
    TK_ARITH = RESERVED_CODE,
    TK_VALUE,
    TK_CAST,
    TK_ENDIF,
    TK_PRINT,

    TK_LOAD,
    TK_MOVE,
    TK_POP,
    TK_COPY,
    TK_CASTB,
    TK_CASTI,
    TK_CASTL,
    TK_CASTF,
    TK_CASTD,

    TK_ADDI,
    TK_ADDL,
    TK_ADDF,
    TK_ADDD,
    TK_SUBI,
    TK_SUBL,
    TK_SUBF,
    TK_SUBD,
    TK_MULI,
    TK_MULL,
    TK_MULF,
    TK_MULD,
    TK_DIVI,
    TK_DIVL,
    TK_DIVF,
    TK_DIVD,

    TK_JUMP,
    TK_JUMPIF,

    TK_END,
};



typedef struct {
    DuaObj obj;
    int c;
    int line;
    int lastLine;
    DuaToken token;
    DuaToken ahead;
    unsigned char* save;
    size_t saveCap;
    size_t saveCur;
    DuaString* data;
    size_t dataCur;
}DuaLex;

extern void
duaInitLex(DuaState* D);
extern DuaLex*
duaNewLex(DuaState* D, DuaString* ts);
extern void
duaNextLex(DuaState* D, DuaLex* lex);
extern int64_t
duaLexInteger(DuaState* D, DuaLex* lex);
extern void
duaLexValue(DuaState* D, DuaLex* lex, DuaValue* sem);
